//
//  LCMainViewController.swift
//  SwiftWeiBo
//
//  Created by LiCheng on 2017/2/8.
//  Copyright © 2017年 LiCheng. All rights reserved.
//

/**
    作用:
     - 用反射添加子控制器
     - 添加发布按钮
     - 读取 微博的未读数
     - 接收通知, 处理用户登录
 */

import UIKit

import SVProgressHUD

/// 主控制器
class LCMainViewController: UITabBarController {

    // MARK: 属性
    /// 定时器
    fileprivate var timer: Timer?


    // MARK: - 系统方法
    override func viewDidLoad() {
        super.viewDidLoad()

        // 添加子控制器
        setupControllers()

        // 添加发布按钮
        setupComposeBttton()

        // 设置定时器获取未读数
        setupTimer()
        
        setupNewFeature()

        delegate = self

        // 注册通知
        NotificationCenter.default.addObserver(self, selector: #selector(userLogin), name: NSNotification.Name(rawValue: LCUserShouldLoginNotification), object: nil)
    }

    /// 代码控制 设备的横竖屏方向
    override var supportedInterfaceOrientations: UIInterfaceOrientationMask {

        return .portrait
        /**
            .porttait:  竖屏(肖像)
            .landscape: 横屏(风景画)
         
            - 用代码控制设备的方向，可以再需要横屏时，单独设置
            - 设置支持的方向之后，当前的控制器以及子控制器都会遵守这个方向
            - 如果播放视频，通常是通过 modal 来展现
         */
    }

    deinit {
        // 销毁定时器
        timer?.invalidate()

        // 注销通知
        NotificationCenter.default.removeObserver(self)
    }


    // MARK: - 监听方法
    /// 用户登录操作
    @objc fileprivate func userLogin(n: Notification) {

        var time = DispatchTime.now()

        // object = overdueToken 有值 说 token 过期
        if n.object != nil {

            // 0. 设置时间
            time = DispatchTime.now() + 2
            // 1. svp 样式
            SVProgressHUD.setDefaultMaskType(.gradient)
            SVProgressHUD.showError(withStatus: "用户登录已超时，请重新登录")
        }

        DispatchQueue.main.asyncAfter(deadline: time) {
            SVProgressHUD.setDefaultMaskType(.clear)
            let nav = UINavigationController(rootViewController: LCOAuthViewController())
            self.present(nav, animated: true, completion: nil)

        }
    }

    
    /// 发布按钮操作
    @objc fileprivate func composeStatusClick() {
        // FIXME: 没有完成
        print("发布微博")
    }

    // MARK: - 私有控件
    /// 发布按钮
    fileprivate lazy var composeButton: UIButton = UIButton.cz_imageButton(
        "tabbar_compose_icon_add",
        backgroundImageName: "tabbar_compose_button")

}

// MARK: 设置界面
extension LCMainViewController {


    /// 设置发布按钮
    fileprivate func setupComposeBttton() {

        // 0. 添加发布按钮
        tabBar.addSubview(composeButton)

        // 1. 计算按钮宽度
        let count = CGFloat(childViewControllers.count)
        let width = tabBar.bounds.width / count

        // 2. 设置边距
        // - 发布按钮的 frame = tabbar 的 bounds 缩进 2个宽度
        composeButton.frame = tabBar.bounds.insetBy(dx: width * 2, dy: 0)

        // 3. 监听方法
        composeButton.addTarget(self, action: #selector(composeStatusClick), for: .touchUpInside)
    }

    /// 设置所有的子控制器
    fileprivate func setupControllers() {


        // 1. 从 bundle 加载json 获取子控制器信息

        //    1>  获取沙盒 json 路径
        let docDir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
        let jsonPath = (docDir as NSString).appendingPathComponent("main.json")

        //    2>  加载 data
        var data = NSData(contentsOfFile: jsonPath)

        //    3>  判断 data 是否有内容
        if data == nil { // 说明沙盒没有文件,从 bundle 加载
            let path = Bundle.main.path(forResource: "main.json", ofType: nil)

            data = NSData(contentsOfFile: path!)
        }

        //   4> 反序列化转换成数组
        guard let array = try? JSONSerialization.jsonObject(with: data! as Data, options: []) as? [[String:AnyObject]]
            else {
            return
        }

        // 2. 遍历数组，循环创建控制器数组
        var vcs = [UIViewController]()
        for dict in array! {
            vcs.append(controller(dict: dict))
        }

        // 3. 设置 子控制器
        viewControllers = vcs
    }

    /// 使用字典创建一个控制器
    ///
    /// - Parameter dict: 字典信息[className, titile, imageName, visitorInfo]
    /// - Returns: 控制器
    private func controller(dict:[String:AnyObject]) -> UIViewController {

        // 1. 获取字典内容
        guard let className = dict["className"] as? String,
            let title = dict["title"] as? String,
            let imageName = dict["imageName"] as? String,
            let visitorInfo = dict["visitorInfo"] as? [String: String],
            let vcType = NSClassFromString(Bundle.main.namespace + "." + className) as? LCBaseViewController.Type

            else {

                // 返回一个标准的视图控制器
                return UIViewController()
        }

        // 2. 创建视图控制器
        let vc = vcType.init()

        // 3. 设置图片
        vc.tabBarItem.image = UIImage(named: "tabbar_" + imageName)
        vc.tabBarItem.selectedImage = UIImage(named: "tabbar_" + imageName + "_selected")?.withRenderingMode(.alwaysOriginal)

        // 4. 设置访客字典信息
        vc.visiorInfoDict = visitorInfo

        // 5. 设置标题颜色
        vc.title = title
        //   - 选中 文字颜色
        vc.tabBarItem.setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.orange], for: .highlighted)
        //   - 字体大小 (系统默认是12号字体) normal 状态下设置
        vc.tabBarItem.setTitleTextAttributes([NSFontAttributeName:UIFont.boldSystemFont(ofSize: 12)], for: .normal)

        // 6. 设置 nav
        //   - 实例化控制器的时候，会调用 push 方法将 rootVC 压栈
        let nav = LCNavigationController(rootViewController: vc)

        // 7. 返回 nav
        return nav
    }
}

// MARK: - 定时器相关方法
extension LCMainViewController {

    func setupTimer()  {

        timer = Timer.scheduledTimer(timeInterval: 40.0, target: self, selector: #selector(updateTimer), userInfo: nil, repeats: true)
    }

    /// 定时器触发方法
    @objc private func updateTimer() {

        if !LCNetworkManager.shared.userLogon {
            return
        }

        LCNetworkManager.shared.loadUnreadCount { (count) in

            print("刷新了\(count)条微博")

            // 设置 首页 tabbarItem 的 badgeNumber
            self.tabBar.items?[0].badgeValue = count > 0 ? "\(count)" : nil
            
            // 设置 app 的 badgeNumber
            UIApplication.shared.applicationIconBadgeNumber = count
        }
    }

}

// MARK: - 代理 UITabBarControllerDelegate
extension LCMainViewController : UITabBarControllerDelegate {

    /// 将要选择 tabbarItem 切换时调用，可以和当前选中的 tab 进行比较
    ///
    /// - Parameters:
    ///   - tabBarController:   tabBarController
    ///   - viewController:     目标控制器
    ///
    /// - Returns:            是否切换到目标控制器
    func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {

        print("切换到\(viewController)")

        // 判断目标控制器是否是 UIiewController
        // - isMember 判断是否是这个类（但不包含子类）
        // - 同时可以 解决 发布按钮的穿帮效果
        if viewController.isMember(of: UIViewController.self) {
            return false
        }else {

            // 1. 获取控制器在数组中的索引
             let idx = (childViewControllers as NSArray).index(of: viewController)

            // 2. 判断当前索引是否是首页，同时 idx 也是首页，重复点击
            if selectedIndex == 0 && idx == selectedIndex {

                // 3. 让表格滚到到顶部
                //    1> 获取控制器
                let nav = childViewControllers[0] as! UINavigationController
                let vc = nav.childViewControllers[0] as! LCBaseViewController
                //    2> 滚动到顶部
                vc.tableView?.setContentOffset(CGPoint(x: 0, y: -64), animated: true)

                // 4. 刷新数据
                //    - 增加延时， 保证 表格先滚到顶部再加载数据
                DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1, execute: { 
                    vc.loadData()

                    // 5. 清除 tabItem 的 bageNumber
                    vc.tabBarItem.badgeValue = nil
                    UIApplication.shared.applicationIconBadgeNumber = 0
                })
            }
            return true
        }
    }
}

// MARK: - 新特性视图处理
extension LCMainViewController {

    /// 是否有版本更新
    private var isNewFeature: Bool {

        // 1. 取当前版本号
        let currentVersion = Bundle.main.version

        // 2. 取出保存在 沙盒 中的版本号
        let path: String = ("version" as NSString).cz_appendDocumentDir()
        let sandboxVersion = (try? String(contentsOfFile: path)) ?? ""

        // 3. 将当前版本号保存在沙盒中
        _ = try? currentVersion.write(toFile: path, atomically: true, encoding: .utf8)

        // 4. 返回两个版本号是否一致 不一致就是新版本
        return currentVersion != sandboxVersion
    }

    /// 设置新特性视图
    fileprivate func setupNewFeature() {

        // 1. 创建视图
        //    - 如果有版本更新 显示 新特性 否则显示 欢迎界面
        let v = isNewFeature ? LCNewFeatureView.newFeatureView() : LCWelcomeView.welcomeView()
        
        // 2. 添加视图
        view.addSubview(v)
    }
}

